﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Collections.Generic;

namespace Xceed.Silverlight.DataGrid
{
  internal class ViewportInfo
  {
    public ViewportInfo()
    {
      this.Elements = new List<ILayoutElement>();
    }

    public double FirstElementOffscreenLength
    {
      get;
      set;
    }
    public double FirstElementLength
    {
      get;
      set;
    }
    public double LastElementOffscreenLength
    {
      get;
      set;
    }
    public double LastElementLength
    {
      get;
      set;
    }

    public IList<ILayoutElement> Elements
    {
      get;
      private set;
    }


    public ILayoutElement FirstElement
    {
      get
      {
        return ( this.Elements.Count > 0 ) ? this.Elements[ 0 ] : null;
      }
    }

    public ILayoutElement LastElement
    {
      get
      {
        return ( this.Elements.Count > 0 ) ? this.Elements[ this.Elements.Count - 1 ] : null;
      }
    }

    public double FirstElementOffscreenPercentLength
    {
      get
      {
        double ratio = this.FirstElementOffscreenLength / this.FirstElementLength;
        if( double.IsNaN( ratio ) )
          return 0d;

        return Math.Min( 1d, ratio );
      }
    }

    public double LastElementOffscreenPercentLength
    {
      get
      {
        double ratio = this.LastElementOffscreenLength / this.LastElementLength;
        if( double.IsNaN( ratio ) )
          return 0d;

        return Math.Min( 1d, ratio );
      }
    }

    public double NbVisibleElements
    {
      get
      {
        double count = 0d;
        for( int i = 0; i < this.Elements.Count; i++ )
        {
          count += 1d;
          ILayoutElement element = this.Elements[ i ];
          if( i == 0 )
          {
            count -= this.FirstElementOffscreenPercentLength;
          }

          if( i == this.Elements.Count - 1 )
          {
            count -= this.LastElementOffscreenPercentLength;
          }
        }
        return count;
      }
    }

    public object GetCurrentElementReference(bool first)
    {
      int itemCount = this.Elements.Count;

      if( itemCount == 0 )
        return null;

      if( itemCount <= 2 )
        return (first) ? this.FirstElement.ReferenceItem : this.LastElement.ReferenceItem;

      return this.GetUnitNavigationReference(first).ReferenceItem;
    }

    public ILayoutElement GetPageNavigationReference( bool first )
    {
      return (first)
               ? this.FirstElement
               : this.LastElement;
    }


    public ILayoutElement GetUnitNavigationReference( bool first )
    {
      ILayoutElement referenceElement = null;
      int itemCount = this.Elements.Count;

      if( itemCount > 0 )
      {
        int limitIndex;
        int secLimitIndex;
        double offscreenLength;

        if( first )
        {
          limitIndex = 0;
          secLimitIndex = 1;
          offscreenLength = this.FirstElementOffscreenLength;
        }
        else
        {
          limitIndex = ( itemCount - 1 );
          secLimitIndex = ( itemCount - 2 );
          offscreenLength = this.LastElementOffscreenLength;
        }

        if( offscreenLength == 0d || itemCount == 1)
        {
          referenceElement = this.Elements[ limitIndex ];
        }
        else
        {
          referenceElement = this.Elements[ secLimitIndex ];
        }
      }

      return referenceElement;
    }
  }
}
